package com.minarto.events {
	import com.minarto.utils.GPool;
	import de.polygonal.core.ObjectPool;
	import flash.events.*;

	
	/**
	 * @author KIMMINHWAN
	 */
	public class EvtManager {
		private var _target:EventDispatcher;
		public function setTarget($taregt:EventDispatcher):void {
			if (_target == $taregt) return;
			if (_target)	clear();
			
			_target = $taregt;
		}
		public function getTarget():EventDispatcher {
			return	_target;
		}
		
		private var _events:Vector.<EvtObj> = new <EvtObj>[];
		
		
		public function addEvt($type:String, $handler:Function, ...$handlerArgs):void {
			var i:uint, o:EvtObj;
			
			if (_target){
				i = _events.length;
				while (i -- ) {
					o = _events[i];
					if (o.type == $type && o.handler == $handler) {
						o.handlerArgs = $handlerArgs;
						return;
					}
				}
	
				o = GPool.getPool(EvtObj).object;
				o.type = $type;
				o.handler = $handler;
				_target.addEventListener($type, _runEvt, false, 0, true);
				o.handlerArgs = $handlerArgs;
				_events.push(o);
			}
		}
		
		
		public function delEvt($type:String, $handler:Function=null):void {
			var i:uint, o:EvtObj, p:ObjectPool;
			
			p = GPool.getPool(EvtObj);
			
			if ($type) {
				i = _events.length;
				
				if (Boolean($handler)) {
					while (i -- ) {
						o = _events[i];
						if (o.type == $type && o.handler == $handler) {
							_target.removeEventListener(o.type, _runEvt);
							_events.splice(i, 1);
							p.object = o;
							
							return;
						}
					}
				}
				else {
					while (i -- ) {
						o = _events[i];
						if (o.type == $type) {
							_target.removeEventListener(o.type, _runEvt);
							_events.splice(i, 1);
							p.object = o;
							
							return;
						}
					}
				}
			}
		}
		
		
		public function clear():void {
			var o:EvtObj, p:ObjectPool;
			
			if (_target) {
				p = GPool.getPool(EvtObj);

				o = _events.pop();
				while (o) {
					_target.removeEventListener(o.type, _runEvt);
					p.object = o;
					o = _events.pop();
				}
			}
		}
		
		
		private function _runEvt($e:Event):void {
			var i:uint, c:uint, o:EvtObj, t:String;
			
			c = _events.length;
			t = $e.type;
			
			for (i = 0; i < c; i++){
				o = _events[i];
				if (o.type == t) {
					o.handler.apply(null, o.handlerArgs);
				}
			}
		}
	}
}